package com.xp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xp.entity.NodeDefinition;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 节点定义数据访问层
 * 提供节点定义的数据库操作方法
 *
 * @author xp
 * @since 2024-01-01
 */
@Mapper
public interface NodeDefinitionMapper extends BaseMapper<NodeDefinition> {

    /**
     * 分页查询节点定义列表
     *
     * @param page 分页参数
     * @param nodeName 节点名称（模糊查询）
     * @param nodeType 节点类型
     * @param category 节点分类
     * @param status 状态
     * @return 分页结果
     */
    IPage<NodeDefinition> selectNodeDefinitionPage(
            Page<NodeDefinition> page,
            @Param("nodeName") String nodeName,
            @Param("nodeType") String nodeType,
            @Param("category") String category,
            @Param("status") Integer status
    );

    /**
     * 根据节点编码查询节点定义
     *
     * @param nodeCode 节点编码
     * @return 节点定义
     */
    @Select("SELECT * FROM node_definition WHERE node_code = #{nodeCode} AND deleted = 0")
    NodeDefinition selectByNodeCode(@Param("nodeCode") String nodeCode);

    /**
     * 根据节点编码和版本查询节点定义
     *
     * @param nodeCode 节点编码
     * @param version 版本号
     * @return 节点定义
     */
    @Select("SELECT * FROM node_definition WHERE node_code = #{nodeCode} AND version = #{version} AND deleted = 0")
    NodeDefinition selectByNodeCodeAndVersion(@Param("nodeCode") String nodeCode, @Param("version") String version);

    /**
     * 根据节点类型查询节点定义列表
     *
     * @param nodeType 节点类型
     * @return 节点定义列表
     */
    @Select("SELECT * FROM node_definition WHERE node_type = #{nodeType} AND status = 1 AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<NodeDefinition> selectByNodeType(@Param("nodeType") String nodeType);

    /**
     * 根据节点分类查询节点定义列表
     *
     * @param category 节点分类
     * @return 节点定义列表
     */
    @Select("SELECT * FROM node_definition WHERE category = #{category} AND status = 1 AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<NodeDefinition> selectByCategory(@Param("category") String category);

    /**
     * 查询所有启用的节点定义
     *
     * @return 节点定义列表
     */
    @Select("SELECT * FROM node_definition WHERE status = 1 AND deleted = 0 ORDER BY category, sort_order ASC, create_time DESC")
    List<NodeDefinition> selectEnabledNodes();

    /**
     * 查询系统内置节点定义
     *
     * @return 节点定义列表
     */
    @Select("SELECT * FROM node_definition WHERE is_system = 1 AND status = 1 AND deleted = 0 ORDER BY sort_order ASC")
    List<NodeDefinition> selectSystemNodes();

    /**
     * 查询自定义节点定义
     *
     * @return 节点定义列表
     */
    @Select("SELECT * FROM node_definition WHERE is_system = 0 AND status = 1 AND deleted = 0 ORDER BY create_time DESC")
    List<NodeDefinition> selectCustomNodes();

    /**
     * 更新节点状态
     *
     * @param id 节点ID
     * @param status 新状态
     * @return 更新行数
     */
    @Update("UPDATE node_definition SET status = #{status}, update_time = NOW() WHERE id = #{id}")
    int updateStatus(@Param("id") Long id, @Param("status") Integer status);

    /**
     * 检查节点编码是否存在
     *
     * @param nodeCode 节点编码
     * @param excludeId 排除的ID（用于更新时检查）
     * @return 存在的数量
     */
    @Select("SELECT COUNT(*) FROM node_definition WHERE node_code = #{nodeCode} AND id != #{excludeId} AND deleted = 0")
    int checkNodeCodeExists(@Param("nodeCode") String nodeCode, @Param("excludeId") Long excludeId);

    /**
     * 获取节点分类列表
     *
     * @return 分类列表
     */
    @Select("SELECT DISTINCT category FROM node_definition WHERE category IS NOT NULL AND deleted = 0 ORDER BY category")
    List<String> selectCategories();

    /**
     * 获取节点类型列表
     *
     * @return 类型列表
     */
    @Select("SELECT DISTINCT node_type FROM node_definition WHERE node_type IS NOT NULL AND deleted = 0 ORDER BY node_type")
    List<String> selectNodeTypes();
}